namespace OFX.Aggregator.WebScraping.Implementation
{
	using System;
	using System.Diagnostics;
	using System.Windows.Forms;

	using Infrastructure;

	using mshtml;

	public class WebBrowserWrapper : IWebBrowser, IDisposable
	{
		private readonly WebBrowser webBrowser;
		private HtmlDocumentWrapper documentWrapper;

		public WebBrowserWrapper()
		{
			this.webBrowser = new WebBrowser();
			this.webBrowser.DocumentCompleted += webBrowser_DocumentCompleted;
		}

		private void webBrowser_DocumentCompleted(object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs e)
		{
			if (DocumentCompleted != null)
				DocumentCompleted(this, new Infrastructure.WebBrowserDocumentCompletedEventArgs(e.Url));
		}

		#region Implementation of IWebBrowser

		public IHtmlDocument Document
		{
			[DebuggerStepThrough]
			get
			{
				if (this.documentWrapper == null)
					this.documentWrapper = new HtmlDocumentWrapper(this.webBrowser.Document);
				return this.documentWrapper;
			}
		}

		public Uri Url
		{
			[DebuggerStepThrough]
			get { return this.webBrowser.Url; }
		}

		public Infrastructure.WebBrowserReadyState ReadyState
		{
			get
			{
				switch (this.webBrowser.ReadyState)
				{
					case System.Windows.Forms.WebBrowserReadyState.Uninitialized:
						return Infrastructure.WebBrowserReadyState.Uninitialized;
					case System.Windows.Forms.WebBrowserReadyState.Loading:
						return Infrastructure.WebBrowserReadyState.Loading;
					case System.Windows.Forms.WebBrowserReadyState.Loaded:
						return Infrastructure.WebBrowserReadyState.Loaded;
					case System.Windows.Forms.WebBrowserReadyState.Interactive:
						return Infrastructure.WebBrowserReadyState.Interactive;
					case System.Windows.Forms.WebBrowserReadyState.Complete:
						return Infrastructure.WebBrowserReadyState.Complete;
					default:
						throw new ArgumentOutOfRangeException();
				}
			}
		}

		public void Navigate(string url)
		{
			HtmlDocument document = this.webBrowser.Document;

			if (document == null)
			{
				this.webBrowser.Navigate(url);
				return;
			}

			((HTMLDocumentClass) document.DomDocument).parentWindow.navigate(url);
		}

		public event EventHandler<Infrastructure.WebBrowserDocumentCompletedEventArgs> DocumentCompleted;

		#endregion

		#region Implementation of IDisposable

		/// <summary>
		/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
		/// </summary>
		/// <filterpriority>2</filterpriority>
		public void Dispose()
		{
			if (this.documentWrapper != null)
				this.documentWrapper.Dispose();
			this.webBrowser.Dispose();
		}

		#endregion
	}
}